using MicroMsg.Common.Utils;
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows;
namespace MicroMsg.Network
{
	public class HttpClient
	{
		public class HttpRequestContext
		{
			public int mStatus;
			public byte[] mBufferInput;
			public byte[] mBufferOutput;
			public int mOutputLength;
			public HttpWebRequest mRequest;
			public HttpWebResponse mResponse;
			public Stream mStreamResponse;
			public Stream mStreamRequest;
			public IAsyncResult mAsyncRequestStreamResult;
			public IAsyncResult mAsyncResponseResult;
			public IAsyncResult mAsyncReadResult;
			public int mSeqID;
			public string mCmdUri;
			public string mHost;
			public event OnHttpReceivedProgressDelegate mProgress;
			public void setProgress(int int_0)
			{
				if (this.mProgress != null)
				{
					this.mProgress(int_0);
				}
			}
			public void release()
			{
				try
				{
					if (this.mStreamResponse != null)
					{
						this.mStreamResponse.Close();
						this.mStreamResponse = null;
					}
					if (this.mResponse != null)
					{
						this.mResponse.Close();
						this.mResponse = null;
					}
				}
				catch (Exception ex)
				{
					Log.smethod_1("Network", string.Concat(new object[]
					{
						"failed to release httpclient context, seq =",
						this.mSeqID,
						", err: ",
						ex.get_Message()
					}));
				}
			}
		}
		public const int BUFFER_SIZE = 8192;
		private const int STATUS_GET_NULL = 0;
		private const int STATUS_GET_DOING = 1;
		private const int STATUS_GET_DONE = 2;
		public HttpClient.HttpRequestContext mHttpContext;
		private Action<byte[]> rspCallback;
		public event DefineHttpHeaderDelegate mDefineHeader;
		public HttpClient(string cmdUri, int int_0, string host)
		{
			this.mHttpContext = new HttpClient.HttpRequestContext();
			this.mHttpContext.mCmdUri = cmdUri;
			this.mHttpContext.mSeqID = int_0;
			this.mHttpContext.mHost = host;
		}
		public void close()
		{
			if (this.mHttpContext != null)
			{
				Log.smethod_5("Network", "httpclient close, uri=" + this.mHttpContext.mCmdUri);
				this.mHttpContext.release();
				this.mHttpContext = null;
			}
		}
		public int getReceivedLength()
		{
			if (this.mHttpContext != null)
			{
				return this.mHttpContext.mOutputLength;
			}
			return 0;
		}
		public SocketError receive(ref byte[] outBuf, ref int int_0, ref string cmdUri)
		{
			if (this.mHttpContext.mStatus != 2)
			{
				return 11004;
			}
			int_0 = this.mHttpContext.mSeqID;
			cmdUri = this.mHttpContext.mCmdUri;
			if (this.mHttpContext.mOutputLength <= 0)
			{
				return -1;
			}
			int mOutputLength = this.mHttpContext.mOutputLength;
			outBuf = new byte[mOutputLength];
			Buffer.BlockCopy(this.mHttpContext.mBufferOutput, 0, outBuf, 0, mOutputLength);
			this.mHttpContext.mStatus = 0;
			this.mHttpContext.mOutputLength = 0;
			return 0;
		}
		public bool send(byte[] data = null, int count = 0, Action<byte[]> action_0 = null)
		{
			try
			{
				this.rspCallback = action_0;
				Uri uri = new Uri(this.mHttpContext.mCmdUri);
				Log.smethod_4("Network", string.Concat(new object[]
				{
					"http send request, len =",
					count,
					" to uri=",
					uri
				}));
				this.mHttpContext.mRequest = (HttpWebRequest)WebRequest.Create(uri);
				if (this.mDefineHeader == null)
				{
					this.mHttpContext.mRequest.set_Method("POST");
					this.mHttpContext.mRequest.set_ContentType("application/octet-stream");
					this.mHttpContext.mRequest.set_UserAgent("wp7 HTTP Client");
					this.mHttpContext.mRequest.set_Accept("*/*");
					this.mHttpContext.mRequest.get_Headers().set_Item("Host", this.mHttpContext.mHost);
					this.mHttpContext.mRequest.get_Headers().set_Item("X-Online-Host", this.mHttpContext.mHost);
					this.mHttpContext.mRequest.get_Headers().set_Item("Cache-Control", "no-cache");
					this.mHttpContext.mRequest.get_Headers().set_Item("Connection", "Keep-Alive");
				}
				else
				{
					this.mDefineHeader(this.mHttpContext.mRequest);
				}
				this.mHttpContext.mStatus = 1;
				if (data != null && count != 0)
				{
					this.mHttpContext.mBufferInput = new byte[count];
					Buffer.BlockCopy(data, 0, this.mHttpContext.mBufferInput, 0, count);
					this.mHttpContext.mAsyncRequestStreamResult = this.mHttpContext.mRequest.BeginGetRequestStream(new AsyncCallback(this.onGetRequestStreamCallback), this.mHttpContext);
				}
				else
				{
					this.mHttpContext.mAsyncResponseResult = this.mHttpContext.mRequest.BeginGetResponse(new AsyncCallback(this.onRecvHttpCallback), this.mHttpContext);
				}
				return true;
			}
			catch (Exception ex)
			{
				Log.smethod_1("Network", "http.send failed: " + ex.get_Message());
				this.mHttpContext.mStatus = 2;
				this.mHttpContext.release();
			}
			return false;
		}
		private void onGetRequestStreamCallback(IAsyncResult asynchronousResult)
		{
			HttpClient.HttpRequestContext httpRequestContext = (HttpClient.HttpRequestContext)asynchronousResult.get_AsyncState();
			try
			{
				HttpWebRequest mRequest = httpRequestContext.mRequest;
				httpRequestContext.mStreamRequest = mRequest.EndGetRequestStream(asynchronousResult);
				httpRequestContext.mStreamRequest.Write(httpRequestContext.mBufferInput, 0, httpRequestContext.mBufferInput.Length);
				httpRequestContext.mStreamRequest.Close();
				httpRequestContext.mAsyncResponseResult = httpRequestContext.mRequest.BeginGetResponse(new AsyncCallback(this.onRecvHttpCallback), httpRequestContext);
			}
			catch (Exception ex)
			{
				Log.smethod_1("Network", "http.onGetRequestStreamCallback failed: " + ex.get_Message());
				httpRequestContext.mStatus = 2;
				httpRequestContext.release();
			}
		}
		private void onRecvHttpCallback(IAsyncResult asynchronousResult)
		{
			HttpClient.HttpRequestContext context = (HttpClient.HttpRequestContext)asynchronousResult.get_AsyncState();
			try
			{
				HttpWebRequest mRequest = context.mRequest;
				context.mResponse = (HttpWebResponse)mRequest.EndGetResponse(asynchronousResult);
				Log.smethod_5("Network", "http return head ,statuscode =  " + context.mResponse.get_StatusCode());
				ServerBulletin.onRecvBulletin(context.mResponse.get_Headers().get_Item("WXBT"));
				Stream responseStream = context.mResponse.GetResponseStream();
				int num = (int)responseStream.get_Length() + 8192;
				byte[] array = new byte[num];
				int num2 = responseStream.Read(array, 0, (int)responseStream.get_Length());
				context.setProgress(num2);
				int num3;
				do
				{
					num3 = responseStream.Read(array, num2, num - num2);
					if (num3 > 0)
					{
						num2 += num3;
						if (num - num2 < 8192)
						{
							num += 8192;
							Array.Resize<byte>(ref array, num);
						}
						context.setProgress(num2);
					}
				}
				while (num3 > 0);
				context.mOutputLength = num2;
				context.mBufferOutput = array;
				context.mStatus = 2;
				if (this.rspCallback != null)
				{
					Deployment.get_Current().get_Dispatcher().BeginInvoke(delegate
					{
						this.rspCallback.Invoke(context.mBufferOutput);
					});
				}
			}
			catch (Exception ex)
			{
				Log.smethod_1("Network", "http.onRecvHttpCallback failed: " + ex.get_Message());
				context.mStatus = 2;
				context.release();
			}
		}
		public static void testHttpClient()
		{
			Thread thread = new Thread(new ThreadStart(HttpClient.testThreadMain));
			thread.Start();
		}
		public static void testThreadMain()
		{
			byte[] data = new byte[1024];
			int count = Util.loadDataFromFile(ref data, "authBodyTestDat");
			HttpClient httpClient = new HttpClient("/cgi-bin/micromsg-bin/auth", 1, null);
			httpClient.send(data, count, null);
			byte[] array = null;
			int num = 0;
			string text = null;
			SocketError socketError;
			do
			{
				Thread.Sleep(100);
				socketError = httpClient.receive(ref array, ref num, ref text);
			}
			while (socketError == 11004);
		}
	}
}
